#include "esp_log.h"
#include "lwip/tcp.h"
#include "lwip/dns.h"
#include "AsyncClient.hpp"
#include "AsyncServer.hpp"
#include "AsyncTCP.hpp"

#define TAG "AsyncClient"

AsyncClient::AsyncClient(Async* sync, AsyncServer* server)
{
    m_async = sync;
    m_server = server;
    reset();
}

AsyncClient::~AsyncClient()
{
    while (m_active.load() || m_event_count.load()) {
        vTaskDelay(pdMS_TO_TICKS(1));
    }
}

void AsyncClient::delete_instance()
{
    delete this;
    ESP_LOGW(TAG, "客户端实例已被销毁.");
}

/// @brief 重置客户端状态
void AsyncClient::reset()
{
    prev = nullptr;
    next = nullptr;
    m_active.store(true);
    m_event_count.store(0);
    m_connection_is_err.store(false);
    on_connected_arg        =   nullptr;
    on_connected_handler    =   nullptr;
    on_disconnected_arg     =   nullptr;
    on_disconnected_handler =   nullptr;
    on_data_sent_arg        =   nullptr;
    on_data_sent_handler    =   nullptr;
    on_error_arg            =   nullptr;
    on_error_handler        =   nullptr;
    on_data_received_arg    =   nullptr;
    on_data_received_handler =  nullptr;
    on_raw_packet_arg       =   nullptr;
    on_raw_packet_handler   =   nullptr;
    m_timeout_arg           =   nullptr;
    m_timeout_handler       =   nullptr;
    m_tx_in_progress        =   false;
    m_connect_later         =   false;
    m_defer_ack             =   false;
    m_last_rx_timestamp     =   0;
    m_last_tx_timestamp     =   0;
    m_rx_timeout_second     =   0;
    m_remote_port           =   0;
    m_ack_timeout_ms        =   CONFIG_ASYNC_MAX_ACK_TIME;
}

/// @brief 初始化客户端连接
/// @param pcb 需要关联的连接[注意：不进行参数有效性检查]
void AsyncClient::init(tcp_pcb* pcb)
{
    m_pcb = pcb;
    m_last_rx_timestamp = get_ms_since_start();

    tcp_arg(m_pcb, this);
    tcp_recv(m_pcb, [](void *arg, tcp_pcb * pcb, pbuf * pb, err_t err) -> err_t {
        return reinterpret_cast<AsyncClient*>(arg)->create_recv_event(arg, pcb, pb, err);
    });
    tcp_sent(m_pcb, [](void* arg, tcp_pcb * pcb, uint16_t len) -> err_t {
        return reinterpret_cast<AsyncClient*>(arg)->create_sent_event(arg, pcb, len);
    });
    tcp_err(m_pcb, [](void* arg, err_t err) {
        return reinterpret_cast<AsyncClient*>(arg)->create_error_event(arg, err);
    });
    tcp_poll(m_pcb, [](void* arg, tcp_pcb * pcb) -> err_t {
        return reinterpret_cast<AsyncClient*>(arg)->create_poll_event(arg, pcb);
    }, 1);
}

/// @brief 准备关闭连接（进入非活跃状态）
void AsyncClient::prepare_close_connection()
{
    m_active.store(false);
}

/// @brief 尝试关闭连接（非活跃状态且事件处理完毕后关闭连接）
void AsyncClient::try_close_connection()
{
    if (!m_active.load() && !m_event_count.load()) {
        if (!m_pcb) {
            ESP_LOGE(TAG, "服务器错误，事件有效期间内：pcb=nullptr");
        }
        if (!m_connection_is_err.load()) {
            tcp_sent(m_pcb, nullptr);
            tcp_recv(m_pcb, nullptr);
            tcp_err(m_pcb, nullptr);
            tcp_poll(m_pcb, nullptr, 0);
            tcp_arg(m_pcb, nullptr);
            auto tmp = m_pcb;
            m_pcb = nullptr;
            if (ESP_OK != close_tcp(tmp)) {
                abort_tcp(tmp);
            }
            if (on_disconnected_handler) {
                on_disconnected_handler(on_disconnected_arg, this);
            }
        }
        m_server->push_client_to_pool(this);
    }
}

/// @brief 与指定的IP、端口建立连接
/// @param ip 对方IP地址
/// @param port 对方服务端口
/// @return 连接成功返回true，否则返回false
bool AsyncClient::connect(ip_addr_t ip, uint16_t port)
{
    if (m_pcb != nullptr) {
        ESP_LOGW(TAG, "当前已存在建立的连接，放弃操作.");
        return false;
    }

    tcp_pcb* pcb = tcp_new_ip_type(IPADDR_TYPE_V4);
    if (!pcb) {
        ESP_LOGE(TAG, "创建PCB失败");
        return false;
    }
    tcp_arg(m_pcb, this);
    tcp_recv(m_pcb, [](void *arg, tcp_pcb * pcb, pbuf * pb, err_t err) -> err_t {
        return reinterpret_cast<AsyncClient*>(arg)->create_recv_event(arg, pcb, pb, err);
    });
    tcp_sent(m_pcb, [](void* arg, tcp_pcb * pcb, uint16_t len) -> err_t {
        return reinterpret_cast<AsyncClient*>(arg)->create_sent_event(arg, pcb, len);
    });
    tcp_err(m_pcb, [](void* arg, err_t err) {
        return reinterpret_cast<AsyncClient*>(arg)->create_error_event(arg, err);
    });
    tcp_poll(m_pcb, [](void* arg, tcp_pcb * pcb) -> err_t {
        return reinterpret_cast<AsyncClient*>(arg)->create_poll_event(arg, pcb);
    }, 1);

    tcp_api_call_t msg;
    msg.pcb = m_pcb;
    msg.conn_addr = &ip;
    msg.conn_port = port;
    msg.conn_fn =  [](void* arg, tcp_pcb * pcb, err_t err) -> err_t {
        return reinterpret_cast<AsyncClient*>(arg)->create_connected_event(arg, pcb, err);
    };
    auto err = tcpip_api_call([](tcpip_api_call_data * data) -> err_t {
        auto* msg = reinterpret_cast<tcp_api_call_t*>(data);
        return tcp_connect(msg->pcb, msg->conn_addr, msg->conn_port, msg->conn_fn);
    },
    (tcpip_api_call_data*)&msg
                             );
    return err == ESP_OK;
}

/// @brief 与指定的Host、端口建立连接
/// @param name 对方主机域名
/// @param port 对方l服务端口
/// @return 连接成功返回true，否则返回false
bool AsyncClient::connect(const char* name, uint16_t port)
{
    ip_addr_t ip;
    m_connect_later = true;
    auto err = dns_gethostbyname(name, &ip, [](const char* name, const ip_addr_t* addr, void* arg) {
        auto* client = reinterpret_cast<AsyncClient*>(arg);
        client->create_DNS_found_event(name, addr, arg);
    },
    this
                                );
    if (err == ESP_OK) {
        m_remote_port = port;
        m_connect_later = false;
        return connect(ip, port);
    } else if (err == ERR_INPROGRESS) {
        m_connect_later = true;
        return true;
    }
    ESP_LOGE(TAG, "解析域名失败");
    return false;
}

/// @brief 等待所有未完成的数据发送完毕后关闭连接
/// @param now
void AsyncClient::close(bool now)
{
    if (m_pcb) {
        notify_lwip_data_processed(m_pcb,  m_unack_rx_bytes);
    }
    prepare_close_connection();
}

/// @brief 获取当前 TCP 发送窗口的可用空间大小（字节）。
/// @return 可发送缓冲区大小
size_t AsyncClient::get_send_buffer_size()
{
    if (m_active.load() && (m_pcb->state == ESTABLISHED)) {
        return tcp_sndbuf(m_pcb);
    }
    return 0;
}

/// @brief 将数据添加到发送队列中，但不立即发送。
/// @param data 数据指针
/// @param size 数据大小
/// @param apiflags 发送标志，默认仅使用TCP_WRITE_FLAG_MORE(不立即发送)
/// TCP_WRITE_FLAG_COPY：数据会被复制进 lwIP 内部内存。如果不设置此标志，数据必须保持有效直到被完全发送完（即 lwIP 不会复制）；
/// TCP_WRITE_FLAG_MORE：表示还有更多数据要发送，不立即触发 PSH（Push）标志。通常用于减少小包数量，提升性能。
/// @return 实际添加至发送缓冲区大小
size_t AsyncClient::add(const void* data, size_t size, uint8_t apiflags)
{
    if (!m_active.load() || size == 0 || data == nullptr) {
        return 0;
    }
    size_t room = get_send_buffer_size();
    if (!room) {
        return 0;
    }
    size_t will_send = room < size ? room : size;

    tcp_api_call_t msg;
    msg.pcb = m_pcb;
    msg.write_data = data;
    msg.write_len = will_send;
    msg.write_apiflag = apiflags;
    auto err = tcpip_api_call([](tcpip_api_call_data * data) -> err_t {
        auto* msg = reinterpret_cast<tcp_api_call_t*>(data);
        return tcp_write(msg->pcb, msg->write_data, msg->write_len, msg->write_apiflag);;
    },
    (tcpip_api_call_data*)&msg
                             );
    return (err != ESP_OK) ? 0 : will_send;
}

/// @brief 触发发送队列中所有通过 add() 添加的数据。
/// @return
bool AsyncClient::send()
{
    if (!m_active.load()) {
        return false;
    }
    tcp_api_call_t msg;
    msg.pcb = m_pcb;
    auto err = tcpip_api_call([](tcpip_api_call_data * data) -> err_t {
        auto* msg = reinterpret_cast<tcp_api_call_t*>(data);
        return tcp_output(msg->pcb);
    },
    (tcpip_api_call_data*)&msg
                             );
    if (err == ESP_OK) {
        m_tx_in_progress = true;
        m_last_tx_timestamp = get_ms_since_start();
        return true;
    }
    return false;
}

/// @brief 尝试向发送缓冲区写入指定数据并发送出去
/// @param apiflags
/// @return 成功发送的数据量
size_t AsyncClient::write(const void* data, size_t size, uint8_t apiflags)
{
    size_t will_send = add(data, size, apiflags);
    if (!will_send || !send()) {
        return 0;
    }
    return will_send;
}

/// @brief 获取连接状态
tcp_state AsyncClient::get_connection_state()
{
    return m_active.load() ? m_pcb->state : CLOSED;
}

/// @brief 获取当前TCP连接的最大报文段长度（Maximum Segment Size, MSS）
uint16_t AsyncClient::get_MSS()
{
    return m_active.load() ? tcp_mss(m_pcb) : 0;
}

/// @brief 获取接收数据超时时间（秒）
/// @return
uint16_t AsyncClient::get_rx_timeout()
{
    return m_rx_timeout_second;
}

/// @brief 设置接收超时时间（秒）
void AsyncClient::set_rx_timeout_second(uint16_t timeout)
{
    m_rx_timeout_second = timeout;
}

/// @brief 获取ack应答超时时间（ms）
uint32_t AsyncClient::get_ack_timeout()
{
    return m_ack_timeout_ms;
}

/// @brief 设置ack应答超时时间
void AsyncClient::set_ack_timeout_ms(uint32_t timeout)
{
    m_ack_timeout_ms = timeout;
}

/// @brief 设置是否启用低延时传输
/// 启用时关闭Nagle算法，会加大数据发送频率
/// 关闭时开启Nagle算法，降低数据发送频率、提高实时性
void AsyncClient::set_nodelay(bool nodelay)
{
    if (!m_active.load()) {
        return;
    }
    if (nodelay) {
        tcp_nagle_disable(m_pcb);
    } else {
        tcp_nagle_enable(m_pcb);
    }
}

/// @brief 获取低延时功能状态
/// @return 开启时返回true
bool AsyncClient::get_nodelay_state()
{
    return m_active.load() ? tcp_nagle_disabled(m_pcb) : false;
}

/// @brief 获取远端IP地址
/// @return 远端IP地址，连接断开时返回0
ip_addr_t AsyncClient::get_remote_IP()
{
    return m_pcb ? m_pcb->remote_ip : (ip_addr_t)IPADDR4_INIT(0);
}

/// @brief 获取本地IP地址
ip_addr_t AsyncClient::get_local_IP()
{
    return m_pcb ? m_pcb->local_ip : (ip_addr_t)IPADDR4_INIT(0);
}

/// @brief 获取对端端口
/// @return 对端端口，连接无效时返回0
uint16_t AsyncClient::get_remote_port()
{
    return m_pcb ? m_pcb->remote_port : 0;
}

/// @brief 获取本地端口
/// @return 本地端口，连接无效时返回0
uint16_t AsyncClient::get_local_port()
{
    return m_pcb ? m_pcb->local_port : 0;
}

/// @brief 确认收到指定大小的数据
size_t AsyncClient::ack(size_t len)
{
    if (len > m_unack_rx_bytes) {
        len = m_unack_rx_bytes;
    }

    if (len) {
        notify_lwip_data_processed(m_pcb, len);
    }
    m_unack_rx_bytes -= len;

    return len;
}

/// @brief 设置是否延迟发送ACK
/// @param defer true表示延迟发送
void AsyncClient::set_defer_ack(bool defer)
{
    m_defer_ack = defer;
}

/// @brief 异步事件数量减1
void AsyncClient::event_count_sub()
{
    m_event_count.fetch_sub(1);
}

/// @brief 异步事件数量加1
void AsyncClient::event_count_add()
{
    m_event_count.fetch_add(1);
}

/// @brief 设置连接成功时的回调函数及其参数
void AsyncClient::set_connected_event_handler(AcConnectHandler cb, void* arg)
{
    on_connected_handler = cb;
    on_connected_arg = arg;
}

/// @brief 设置连接断开时的回调函数及其参数
void AsyncClient::set_disconnected_event_handler(AcConnectHandler cb, void* arg)
{
    on_disconnected_handler = cb;
    on_disconnected_arg = arg;
}

/// @brief 设置接收到ACK响应时的回调函数及其参数
void AsyncClient::set_ack_event_handler(AcAckHandler cb, void* arg)
{
    on_data_sent_handler = cb;
    on_data_sent_arg = arg;
}

/// @brief 设置连接错误/异常时的回调函数及其参数
void AsyncClient::set_error_event_handler(AcErrorHandler cb, void* arg)
{
    on_error_handler = cb;
    on_error_arg = arg;
}

/// @brief 设置接收到数据时的回调函数
void AsyncClient::set_data_received_handler(AcDataHandler cb, void* arg)
{
    on_data_received_handler = cb;
    on_data_received_arg = arg;
}

/// @brief 设置接收到完整数据包时的回调函数
void AsyncClient::set_raw_packet_received_handler(AcPacketHandler cb, void* arg)
{
    on_raw_packet_handler = cb;
    on_raw_packet_arg = arg;
}

/// @brief 设置超时事件的回调函数
void AsyncClient::set_timeout_event_handler(AcTimeoutHandler cb, void* arg)
{
    m_timeout_handler = cb;
    m_timeout_arg = arg;
}

/// @brief 设置定期轮询的回调函数
void AsyncClient::set_poll_event_handler(AcConnectHandler cb, void* arg)
{
    m_poll_handler = cb;
    m_poll_arg = arg;
}

/// @brief 接收数据事件处理程序
/// @param pcb 关联的协议控制块
/// @param pb 数据指针
/// @param err .......................................
err_t AsyncClient::handle_received_event(tcp_pcb* pcb, pbuf* pb, err_t err)
{
    m_event_count.fetch_sub(1);
    if (pb != nullptr) {
        m_last_rx_timestamp = get_ms_since_start();
        m_defer_ack = false;
        auto* merged = pbuf_coalesce(pb, PBUF_RAW);
        if (merged != pb) {
            if (on_raw_packet_handler != nullptr) {
                on_raw_packet_handler(on_raw_packet_arg, this, merged);
            } else {
                auto mergedLength = merged->tot_len;
                if (on_data_received_handler != nullptr) {
                    on_data_received_handler(on_data_received_arg, this, merged->payload, mergedLength);
                }
                if (!m_defer_ack) {
                    notify_lwip_data_processed(m_pcb, mergedLength);
                } else {
                    m_unack_rx_bytes += mergedLength;
                }
                pbuf_free(merged);
            }
        } else {
            do {
                auto* current = pb;
                pb = pb->next;
                current->next = nullptr;
                if (on_raw_packet_handler != nullptr) {
                    on_raw_packet_handler(on_raw_packet_arg, this, current);
                } else {
                    auto currentLength = current->len;
                    if (on_data_received_handler) {
                        on_data_received_handler(on_data_received_arg, this, current->payload, currentLength);
                    }
                    if (m_defer_ack) {
                        m_unack_rx_bytes += currentLength;
                    } else {
                        notify_lwip_data_processed(m_pcb, currentLength);
                    }
                    pbuf_free(current);
                }
            } while (pb != nullptr);
        }
    }
    return ESP_OK;
}

/// @brief 连接建立事件处理程序
/// @param pcb 关联的协议控制块
/// @param err ........
err_t AsyncClient::handle_connected_event(tcp_pcb* pcb, err_t err)
{
    m_event_count.fetch_sub(1);
    m_pcb = reinterpret_cast<tcp_pcb*>(pcb);
    if (m_pcb) {
        m_last_rx_timestamp = get_ms_since_start();
        m_tx_in_progress = false;
    }
    if (on_connected_handler) {
        on_connected_handler(on_connected_arg, this);
    }
    return ESP_OK;
}

/// @brief FIN事件处理程序
/// @param pcb 关联的协议控制块
/// @param err ..........
err_t AsyncClient::handle_FIN_event(tcp_pcb* pcb, err_t err)
{
    m_event_count.fetch_sub(1);
    if (m_connection_is_err) {
        return ESP_OK;
    }
    prepare_close_connection();
    return ESP_OK;
}

/// @brief 错误事件处理程序
/// @param err
void AsyncClient::handle_error_event(err_t err)
{
    prepare_close_connection();
    m_event_count.fetch_sub(1);
    if (m_connection_is_err) {
        return;
    }
    if (on_error_handler) {
        on_error_handler(on_error_arg, this, err);
    }
}

/// @brief 数据成功发送事件处理事件
/// @param pcb 关联的协议控制块
/// @param len 发送的数据长度
err_t AsyncClient::handle_sent_event(tcp_pcb* pcb, uint16_t len)
{
    m_event_count.fetch_sub(1);
    m_last_rx_timestamp = get_ms_since_start();
    m_tx_in_progress = false;
    if (on_data_sent_handler) {
        on_data_sent_handler(on_data_sent_arg, this, len, get_ms_since_start() - m_last_tx_timestamp);
    }
    return ESP_OK;
}

/// @brief 轮询事件处理程序
/// @param pcb 关联的协议控制块
err_t AsyncClient::handle_poll_event(tcp_pcb* pcb)
{
    m_event_count.fetch_sub(1);
    if (m_connection_is_err.load()) {
        return ESP_FAIL;
    }

    if (m_pcb == nullptr || pcb != m_pcb) {
        ESP_LOGW(TAG, "PCB无效或已被释放，忽略本次轮询操作。");
        return ESP_ERR_INVALID_ARG;
    }

    if (m_tx_in_progress && is_timeout(m_last_tx_timestamp, m_ack_timeout_ms)) {
        m_tx_in_progress = false;
        ESP_LOGW(TAG, "Ack Timeout.");
        if (m_timeout_handler) {
            m_timeout_handler(m_timeout_arg, this, get_ms_since_start() - m_last_tx_timestamp);
            return ERR_TIMEOUT;
        }
    }
    if (is_timeout(m_last_rx_timestamp, m_rx_timeout_second * 1000)) {
        ESP_LOGW(TAG, "RX timeout.");
        prepare_close_connection();
        return ERR_TIMEOUT;
    }
    if (m_poll_handler) {
        m_poll_handler(m_poll_arg, this);
    }
    return ESP_OK;
}

/// @brief DNS解析成功事件处理程序
/// @param ipaddr 解析的IP地址
void  AsyncClient::handle_DNS_found_event(ip_addr_t* ipaddr)
{
    m_event_count.fetch_sub(1);
    if (ipaddr && ipaddr->u_addr.ip4.addr) {
        connect(*ipaddr, m_remote_port);
    } else {
        if (on_error_handler) {
            on_error_handler(on_error_arg, this, -55);
        }
        prepare_close_connection();
    }
}

/// @brief 创建一个接收到数据包/FIN事件..............返回值修改
err_t AsyncClient::create_recv_event(void *arg, tcp_pcb *pcb, pbuf *pb, err_t err)
{
    if (!m_active.load()) {
        return ESP_FAIL;
    }
    auto* e = m_async->get_event_from_pool();
    if (e == nullptr) {
        ESP_LOGE(TAG, "从事件池取出事件失败");
        return ESP_FAIL;
    }
    e->arg = arg;
    if (pb != nullptr) {
        e->type =  LWIP_TCP_RECV;
        e->recv_pcb = pcb;
        e->recv_pb = pb;
        e->recv_err = err;
    } else {
        m_active.store(false);
        e->type = LWIP_TCP_FIN;
        e->fin_pcb = pcb;
        e->fin_err = err;
    }
    if (m_async->send_event_to_queue(e) != true) {
        ESP_LOGE(TAG, "发送事件到队列中失败，事件被丢弃！");
        if (e->type ==  LWIP_TCP_RECV) {
            pbuf_free(pb);
        }
        m_async->push_event_to_pool(e);
        return ESP_FAIL;
    }
    m_event_count.fetch_add(1);
    return ESP_OK;
}

/// @brief 创建一个数据已发送事件
err_t AsyncClient::create_sent_event(void* arg, tcp_pcb* pcb, uint16_t len)
{

    if (!m_active.load()) {
        return ESP_FAIL;
    }
    auto* e = m_async->get_event_from_pool();
    if (e == nullptr) {
        ESP_LOGE(TAG, "从事件池取出事件失败");
        return ESP_FAIL;
    }
    e->type = LWIP_TCP_SENT;
    e->arg = arg;
    e->sent_pcb = pcb;
    e->sent_len = len;
    if (m_async->send_event_to_queue(e) != true) {
        ESP_LOGE(TAG, "发送事件到队列中失败，事件被丢弃！");
        m_async->push_event_to_pool(e);
        return ESP_FAIL;
    }
    m_event_count.fetch_add(1);
    return ESP_OK;
}

void AsyncClient::create_error_event(void* arg, err_t err)
{
    m_connection_is_err.store(true);
    if (!m_active.load()) {
        return;
    }
    m_active.store(false);
    auto* e = m_async->get_event_from_pool();
    if (e == nullptr) {
        ESP_LOGE(TAG, "从事件池取出事件失败");
        return;
    }
    e->type = LWIP_TCP_ERROR;
    e->arg = arg;
    e->err_err = err;
    if (m_async->send_event_to_queue(e) != true) {
        ESP_LOGE(TAG, "发送事件到队列中失败，事件被丢弃！");
        m_async->push_event_to_pool(e);
        return;
    }
    m_event_count.fetch_add(1);
}

err_t AsyncClient::create_poll_event(void* arg, tcp_pcb* pcb)
{
    if (!m_active.load()) {
        return ESP_FAIL;
    }
    auto* e = m_async->get_event_from_pool();
    if (e == nullptr) {
        ESP_LOGE(TAG, "从事件池取出事件失败");
        return ESP_FAIL;
    }
    e->type = LWIP_TCP_POLL;
    e->arg = arg;
    e->poll_pcb = pcb;
    if (m_async->send_event_to_queue(e) != true) {
        ESP_LOGE(TAG, "发送事件到队列中失败，事件被丢弃！");
        m_async->push_event_to_pool(e);
        return ESP_FAIL;
    }
    m_event_count.fetch_add(1);
    return ESP_OK;
}

err_t AsyncClient::create_connected_event(void* arg, tcp_pcb* pcb, err_t err)
{
    if (!m_active.load()) {
        return ESP_FAIL;
    }
    auto* e = m_async->get_event_from_pool();
    if (e == nullptr) {
        ESP_LOGE(TAG, "从事件池取出事件失败");
        return ESP_FAIL;
    }
    e->type = LWIP_TCP_CONNECTED;
    e->arg = arg;
    e->conn_pcb = pcb;
    e->conn_err = err;
    if (m_async->send_event_to_queue(e) != true) {
        ESP_LOGE(TAG, "发送事件到队列中失败，事件被丢弃！");
        m_async->push_event_to_pool(e);
        return ESP_FAIL;
    }
    m_event_count.fetch_add(1);
    return ESP_OK;
}

void  AsyncClient::create_DNS_found_event(const char* name, const ip_addr_t* addr, void* arg)
{
    if (!m_active.load()) {
        return;
    }
    auto* e = m_async->get_event_from_pool();
    if (e == nullptr) {
        ESP_LOGE(TAG, "从事件池取出事件失败");
        return;
    }
    e->type = LWIP_TCP_DNS;
    e->arg = arg;
    // e->data.dns.name = name;
    if (addr != nullptr) {
        memcpy(&e->dns_addr, addr, sizeof(ip_addr));
    } else {
        memset(&e->dns_addr, 0, sizeof(e->dns_addr));
    }
    if (m_async->send_event_to_queue(e) != true) {
        ESP_LOGE(TAG, "发送事件到队列中失败，事件被丢弃！");
        m_async->push_event_to_pool(e);
        return;
    }
    m_event_count.fetch_add(1);
}

/// @brief 通知lwip数据已被处理，可以释放（不会对参数进行检查）
void AsyncClient::notify_lwip_data_processed(tcp_pcb* pcb, uint16_t len)
{
    tcp_api_call_t msg;
    msg.pcb = pcb;
    msg.recv_len = len;
    tcpip_api_call([](tcpip_api_call_data * data) -> err_t {
        auto* msg = reinterpret_cast<tcp_api_call_t*>(data);
        tcp_recved(msg->pcb, msg->recv_len);
        return ESP_OK;
    },
    (tcpip_api_call_data*)&msg
                  );
}

AsyncClient &AsyncClient::operator=(const AsyncClient &other)
{
    if (m_pcb) {
        prepare_close_connection();
    }

    m_pcb = other.m_pcb;
    if (m_pcb) {
        m_last_rx_timestamp = get_ms_since_start();
        tcp_arg(m_pcb, this);
        tcp_recv(m_pcb, [](void *arg, tcp_pcb * pcb, pbuf * pb, err_t err) -> err_t {
            return reinterpret_cast<AsyncClient*>(arg)->create_recv_event(arg, pcb, pb, err);
        });
        tcp_sent(m_pcb, [](void* arg, tcp_pcb * pcb, uint16_t len) -> err_t {
            return reinterpret_cast<AsyncClient*>(arg)->create_sent_event(arg, pcb, len);
        });
        tcp_err(m_pcb, [](void* arg, err_t err) {
            return reinterpret_cast<AsyncClient*>(arg)->create_error_event(arg, err);
        });
        tcp_poll(m_pcb, [](void* arg, tcp_pcb * pcb) -> err_t {
            return reinterpret_cast<AsyncClient*>(arg)->create_poll_event(arg, pcb);
        }, 1);
    }
    return *this;
}
AsyncClient &AsyncClient::operator+=(const AsyncClient &other)
{
    if (next == nullptr) {
        next = (AsyncClient*)&other;
        next->prev = this;
    } else {
        AsyncClient* c = next;
        while (c->next != nullptr) {
            c = c->next;
        }
        c->next = (AsyncClient*)&other;
        c->next->prev = this;
    }
    return *this;
}
